using System;
using UnityEngine;
using UnityEngine.EventSystems;

namespace Gj
{
    public class CanvasHandleItemHelper : NodeHelper, IPointerDownHandler, IPointerUpHandler, IDragHandler
    {
        public GameObject item;
        public float speed = 10f;
        public bool motion;
        public bool invert;
        private bool allow;
        private Vector2 deltaPos = Vector2.zero;
        private bool doing;
        private float moveTime;
        private bool moving;
        private Vector2 oldPosition = Vector2.zero;
        private readonly float pre = 10;
        private float waitTime = 1;

        protected override BindDataType bindDataType => BindDataType.Bool;

        // Update is called once per frame
        private void Update()
        {
            if (motion && moving && !doing)
            {
                if (Time.time < moveTime + waitTime)
                {
                    deltaPos = new Vector2(deltaPos.x - deltaPos.x / pre / waitTime,
                        deltaPos.y - deltaPos.y / pre / waitTime);
                    item.transform.Rotate(deltaPos.y, deltaPos.x * -1, 0, Space.World);
                }
                else if (Time.time > moveTime + waitTime && moving)
                {
                    moving = false;
                    Emit(UIEvent.End);
                }
            }
        }

        public void OnDrag(PointerEventData eventData)
        {
            if (!allow) return;
            var newPosition = eventData.position;
            if (oldPosition != Vector2.zero)
            {
                deltaPos = newPosition - oldPosition;
                item.transform.Rotate(deltaPos.y, deltaPos.x * -1, 0, Space.World);
                waitTime = (Math.Abs(deltaPos.x) + Math.Abs(deltaPos.y)) / 4 / speed;
                moveTime = Time.time;
            }

            oldPosition = newPosition;
        }

        public void OnPointerDown(PointerEventData eventData)
        {
            if (!allow) return;

            moving = true;
            doing = true;
            oldPosition = Vector2.zero;
            Emit(UIEvent.Start);
        }

        public void OnPointerUp(PointerEventData eventData)
        {
            doing = false;
            Emit(UIEvent.End);
        }

        protected override void BindData(bool b)
        {
            allow = invert ? !b : b;
        }
    }
}